package com.example.springsecurity.common.config;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.springsecurity.common.enums.GlobalExceptionEnum;
import com.example.springsecurity.common.enums.StatusEnums;
import com.example.springsecurity.common.exception.BizException;
import com.example.springsecurity.entity.*;
import com.example.springsecurity.mapper.*;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.example.springsecurity.common.constant.Constant.REDIS_LOGIN_PATH;

/**
 * @Description：Security安全认证框架默认用户详情接口实现类
 * @Author： fengcheng
 * @Date： 2024/12/18 13:44
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    // 这里是框架提供的数据处理类，在内存中操作数据
    // @Resource
    // private InMemoryUserDetailsManager userDetailsManager;

    @Resource
    private SystemInitDataConfig systemInitDataConfig;

    @Resource
    private RedisCache redisCache;

    @Resource
    private SystemMenuMapper systemMenuMapper;

    @Resource
    private SystemRoleMapper systemRoleMapper;

    @Resource
    private SystemTenantMapper systemTenantMapper;

    @Resource
    private SystemUserMapper systemUserMapper;

    @Resource
    private SystemUserRoleMapper systemUserRoleMapper;

    @Resource
    private SystemRoleMenuMapper systemRoleMenuMapper;

    /**
     * @Description：构建【SystemUser】对象
     * @Author：fengcheng
     * @Date：2024/12/18 13:50
     * @Param：username
     * @Param：password
     * @Param：roles
     * @ParamsType：[java.lang.String, java.lang.String, java.lang.String]
     * @Return：com.example.springsecurity.dao.SystemUser
     */
    public static SystemUser buildSystemUser(String username, String password, String userPhone) {
        SystemUser systemUser = new SystemUser();
        systemUser.setTenantId(1L);
        systemUser.setUsername(username);
        systemUser.setPassword(password);
        systemUser.setMobile(userPhone);
        systemUser.setEmail("zdxlz@163.com");
        systemUser.setStatus(0);
        systemUser.setUserType("SUPER");
        systemUser.setLoginIp("0.0.0.0");
        systemUser.setLoginDate(new Date());
        systemUser.setEnableCaptcha(0);
        systemUser.setDeleted(0);
        systemUser.setRemark("系统内置用户");
        systemUser.setCreateBy("SYSTEM");
        systemUser.setCreateTime(new Date());
        return systemUser;
    }

    /**
     * @Description：通过【用户名称】查询用户对象信息
     * @Author：fengcheng
     * @Date：2024/12/18 13:51
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：org.springframework.security.core.userdetails.UserDetails
     */
    @Override
    public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException {
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUser::getMobile, mobile);

        SystemUser user = systemUserMapper.selectOne(queryWrapper);
        // 用户不存在
        if (ObjectUtil.isEmpty(user))
            throw new BizException(GlobalExceptionEnum.ERROR_USER_NOT_EXIST.getCode(), GlobalExceptionEnum.ERROR_USER_NOT_EXIST.getMessage());

        // 用户停用
        if (Integer.parseInt(StatusEnums.DISABLE.getCode()) == user.getStatus())
            throw new BizException(GlobalExceptionEnum.USER_DISABLED.getCode(), GlobalExceptionEnum.USER_DISABLED.getMessage());

        // 获取用户菜单权限标识
        List<String> permissions = systemMenuMapper.selectPermsByUserId(user.getId());

        // 获取用户角色
        List<String> userRole = systemRoleMapper.getUserRole(user.getId());

        SystemUserLoginDetail userDetails = new SystemUserLoginDetail(user, permissions, userRole);

        //把完整的用户信息存入redis【mobile】作为key
        redisCache.setCacheObject(REDIS_LOGIN_PATH + mobile, userDetails);
        return userDetails;
    }


    /**
     * @Description：校验租户是否存在
     * @Author：fengcheng
     * @Date：2024/12/19 11:29
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：boolean
     */
    public boolean tenantIsExists(String tenantName) {
        LambdaQueryWrapper<SystemTenant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemTenant::getName, tenantName);
        return systemTenantMapper.exists(queryWrapper);
    }

    /**
     * @Description：初始化租户
     * @Author：fengcheng
     * @Date：2024/12/18 13:49
     * @Param：username
     * @Param：password
     * @Param：roles
     * @ParamsType：[java.lang.String, java.lang.String, java.lang.String]
     * @Return：void
     */
    public void createTenant() {
        SystemTenant systemTenant = systemInitDataConfig.getSystemTenant();
        if (CollectionUtils.isEmpty(systemTenantMapper.selectList(null))) systemTenantMapper.insert(systemTenant);
    }

    /**
     * @Description：校验用户是否存在
     * @Author：fengcheng
     * @Date：2024/12/19 11:29
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：boolean
     */
    public boolean userIsExists(String userName) {
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUser::getMobile, userName);
        return systemUserMapper.exists(queryWrapper);
    }

    /**
     * @Description：初始化用户
     * @Author：fengcheng
     * @Date：2024/12/18 13:49
     * @Param：username
     * @Param：password
     * @Param：roles
     * @ParamsType：[java.lang.String, java.lang.String, java.lang.String]
     * @Return：void
     */
    public void createUser() {
        SystemUser systemUser = systemInitDataConfig.getSystemUser();
        if (CollectionUtils.isEmpty(systemUserMapper.selectList(null))) systemUserMapper.insert(systemUser);
    }

    /**
     * @Description：校验角色是否存在
     * @Author：fengcheng
     * @Date：2024/12/19 11:29
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：boolean
     */
    public boolean roleIsExists(String roleName) {
        LambdaQueryWrapper<SystemRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemRole::getName, roleName);
        return systemRoleMapper.exists(queryWrapper);
    }

    /**
     * @Description：初始化角色
     * @Author：fengcheng
     * @Date：2024/12/18 13:49
     * @Param：username
     * @Param：password
     * @Param：roles
     * @ParamsType：[java.lang.String, java.lang.String, java.lang.String]
     * @Return：void
     */
    public void createRole() {
        SystemRole systemRole = systemInitDataConfig.getSystemRole();
        if (CollectionUtils.isEmpty(systemRoleMapper.selectList(null))) systemRoleMapper.insert(systemRole);
    }

    /**
     * @Description：校验用户角色是否存在
     * @Author：fengcheng
     * @Date：2025/1/20 14:20
     * @Param：userId
     * @Param：roleId
     * @ParamsType：[java.lang.String, java.lang.String]
     * @Return：boolean
     */
    public boolean uesrRoleIsExists(Long userId, Long roleId) {
        LambdaQueryWrapper<SystemUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUserRole::getUserId, userId);
        queryWrapper.eq(SystemUserRole::getRoleId, roleId);
        return systemUserRoleMapper.exists(queryWrapper);
    }

    /**
     * @Description：初始化用户角色
     * @Author：fengcheng
     * @Date：2025/1/20 14:26
     * @Return：void
     */
    public void createUesrRole() {
        SystemUserRole systemUserRole = systemInitDataConfig.getSystemUserRole();
        if (CollectionUtils.isEmpty(systemUserRoleMapper.selectList(null))) systemUserRoleMapper.insert(systemUserRole);
    }

    /**
     * @Description：校验菜单是否存在
     * @Author：fengcheng
     * @Date：2024/12/19 11:29
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：boolean
     */
    public boolean menuIsExists(List<String> menuNames) {
        return systemMenuMapper.existsByMenuName(menuNames) == 0;
    }

    /**
     * @Description：初始化菜单
     * @Author：fengcheng
     * @Date：2024/12/18 13:49
     * @Param：username
     * @Param：password
     * @Param：roles
     * @ParamsType：[java.lang.String, java.lang.String, java.lang.String]
     * @Return：void
     */
    public void createMenu() {
        List<SystemMenu> systemMenus = systemInitDataConfig.getSystemMenu();
        if (CollectionUtils.isEmpty(systemMenuMapper.selectList(null)) && !CollectionUtils.isEmpty(systemMenus)) systemMenuMapper.insert(systemMenus);
    }

    /**
     * @Description：校验角色菜单是否存在
     * @Author：fengcheng
     * @Date：2025/1/20 14:20
     * @Param：userId
     * @Param：roleId
     * @ParamsType：[java.lang.String, java.lang.String]
     * @Return：boolean
     */
    public boolean roleMenuIsExists(Long roleId, Long menuId) {
        LambdaQueryWrapper<SystemRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemRoleMenu::getRoleId, roleId);
        queryWrapper.eq(SystemRoleMenu::getMenuId, menuId);
        return systemRoleMenuMapper.exists(queryWrapper);
    }

    /**
     * @Description：初始化角色菜单
     * @Author：fengcheng
     * @Date：2025/1/20 14:26
     * @Return：void
     */
    public void createRoleMenu() {
        List<SystemRoleMenu> systemRoleMenus = systemInitDataConfig.getSystemRoleMenu();
        if (CollectionUtils.isEmpty(systemRoleMenuMapper.selectList(null)) && !CollectionUtils.isEmpty(systemRoleMenus))
            systemRoleMenuMapper.insert(systemRoleMenus);
    }

    /**
     * @Description：更新用户登陆密码
     * @Author：fengcheng
     * @Date：2024/12/18 13:54
     * @Param：username
     * @Param：password
     * @ParamsType：[java.lang.String, java.lang.String]
     * @Return：void
     */
    public void updatePassword(String userName, String password) {
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUser::getUsername, userName);
        SystemUser selectOne = systemUserMapper.selectOne(queryWrapper);
        if (ObjectUtils.isNotEmpty(selectOne)) {
            selectOne.setUsername(userName);
            selectOne.setPassword(password);
            systemUserMapper.updateById(selectOne);
        } else {
            throw new BizException("通过【用户名: " + userName + "】没有查询到数据，操作失败！");
        }
    }

    /**
     * @Description：通过【用户名称】这一列删除用户信息
     * @Author：fengcheng
     * @Date：2024/12/18 13:54
     * @Param：username
     * @ParamsType：[java.lang.String]
     * @Return：void
     */
    public void deleteUser(String username) {
        Map<String, Object> columnMap = Maps.newHashMap();
        columnMap.put("username", username);
        systemUserMapper.deleteByMap(columnMap);
    }

}
